#include "Transition.h"
#include "PDA.h"

void doS () {
    char c;
    int i;
    i = FindTop('S');
    while (i < 9) {
        Pop(&x[i],&c);
        Push(&x[i],'e');
        Push(&x[i],'Q');
        Push(&x[i],'b');
        Push(&x[i],'K');
        i = FindTop('S');
    }
}

void doQ () {
    char c;
    int i;
    int j;
    Stack dummy;
    CreateEmpty(&dummy);
    i = FindTop('Q');
    Pop(&x[i],&c);
    j = FindEmpty();
    while(!IsEmpty(x[i])) {
        Pop(&x[i],&c);
        Push(&dummy,c);
    }
    while(!IsEmpty(dummy)) {
        Pop(&dummy,&c);
        Push(&x[i],c);
        Push(&x[j],c);
        Push(&x[j+1],c);
        Push(&x[j+2],c);
        Push(&x[j+3],c);
        Push(&x[j+4],c);
        Push(&x[j+5],c);
        Push(&x[j+6],c);
    }
    Push(&x[j],'Q');
    Push(&x[j],'S');
    //Push(&x[j],'K');
    Push(&x[j],'d');
    Push(&x[j],'K');
    Push(&x[j],'C');
    Push(&x[j],'K');
    Push(&x[j],'w');
    Push(&x[j+1],'Q');
    Push(&x[j+1],'C');
    Push(&x[j+1],'K');
    Push(&x[j+1],'u');
    Push(&x[j+1],'Q');
    Push(&x[j+1],'r');
    Push(&x[j+2],'Q');
    Push(&x[j+2],')');
    Push(&x[j+2],'y');
    Push(&x[j+2],'(');
    Push(&x[j+2],'K');
    Push(&x[j+2],'m');
    Push(&x[j+3],'Q');
    Push(&x[j+3],'A');
    Push(&x[j+3],'S');
    Push(&x[j+3],'t');
    Push(&x[j+3],'K');
    Push(&x[j+3],'C');
    Push(&x[j+3],'K');
    Push(&x[j+3],'i');
    Push(&x[j+4],'Q');
    Push(&x[j+4],')');
    Push(&x[j+4],'O');
    Push(&x[j+4],'(');
    Push(&x[j+4],'K');
    Push(&x[j+4],'o');
    Push(&x[j+5],'Q');
    Push(&x[j+5],'K');
    Push(&x[j+6],'Q');
    Push(&x[j+6],'K');
    Push(&x[j+6],'B');
}

void doA() {
    Stack dummy;
    CreateEmpty(&dummy);
    char c;
    int i,j;
    j = FindEmpty();
    i = FindTop('A');
    Pop(&x[i],&c);
    while(!IsEmpty(x[i])) {
        Pop(&x[i],&c);
        Push(&dummy,c);
    }
    while(!IsEmpty(dummy)) {
        Pop(&dummy,&c);
        Push(&x[i],c);
        Push(&x[j],c);
    }
    Push(&x[j],'S');
    Push(&x[j],'K');
    Push(&x[j],'n');
}

void doB () {
    Stack dummy;
    CreateEmpty(&dummy);
    char c;
    int i;
    i = FindTop('B');
    Pop(&x[i],&c);
    Push(&x[i],'K');
    Push(&x[i],'O');
    Push(&x[i],'=');
    Push(&x[i],'y');
}

void doC () {
    char c;
    int i;
    i = FindTop('C');
    Pop(&x[i],&c);
    Push(&x[i],')');
    Push(&x[i],'O');
    Push(&x[i],'p');
    Push(&x[i],'O');
    Push(&x[i],'(');
}

void doK () {
    Stack dummy;
    CreateEmpty(&dummy);
    char c;
    int i,j;
    j = FindEmpty();
    i = FindTop('K');
    Pop(&x[i],&c);
    while(!IsEmpty(x[i])) {
        Pop(&x[i],&c);
        Push(&dummy,c);
    }
    while(!IsEmpty(dummy)) {
        Pop(&dummy,&c);
        Push(&x[i],c);
        Push(&x[j],c);
    }
    Push(&x[j],'}');
    Push(&x[j],'{');
}

void checkBuKu (myKata * kataTemp, boolean * cek) {
    int i;
    char c;
    boolean found;
    found = false;
    i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if ((*kataTemp).kata[0] == '(') {
                Pop(&x[i],&c);
                found = true;
            } else {
                DeleteStack(&x[i]);
            }
        }
        i++;
    }
    if (!found) {
        (*cek) = false;
    } else {
        (*kataTemp) = getSubString((*kataTemp),2,(*kataTemp).length);
    }
}

void checkTuKu (myKata * kataTemp, boolean * cek) {
    int i;
    char c;
    boolean found;
    found = false;
    i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if ((*kataTemp).kata[0] == ')') {
                Pop(&x[i],&c);
                found = true;
            } else {
                DeleteStack(&x[i]);
            }
        }
        i++;
    }
    if (!found) {
        (*cek) = false;
    } else {
        (*kataTemp) = getSubString((*kataTemp),2,(*kataTemp).length);
    }
}

void checkO (myKata * kataTemp, boolean *cek) {
    char c;
    int i;
    int k;
    int l;
    int m;
    boolean a = false;
    int j = 0;
    myKata dump;
    Stack dummy;
    createEmpty(&dump);
    i = FindTop('O');
    if ((*kataTemp).kata[((*kataTemp).length) - 1] == ')') {
        while (!IsPembanding((*kataTemp),j) && (j != (*kataTemp).length-1)) {
            dump.kata[j] = (*kataTemp).kata[j];
            j++;
        }
    } else {
        while (!IsPembanding((*kataTemp),j) && (j != (*kataTemp).length)) {
            dump.kata[j] = (*kataTemp).kata[j];
            j++;
        }
    }
    dump.length = j;

    //while (i < 9) {
        Pop(&x[i],&c);
        l = FindEmpty();
        k = 0;
        while (k < 2) {
            CreateEmpty(&dummy);
            while(!IsEmpty(x[i])) {
                Pop(&x[i],&c);
                Push(&dummy,c);
            }
            while(!IsEmpty(dummy)) {
                Pop(&dummy,&c);
                Push(&x[l],c);
                Push(&x[i],c);
            }
            if (k == 0) {
                Push(&x[l],')');
                Push(&x[l],'O');
                Push(&x[l],'(');
            } else if (k == 1) {
                Push(&x[l],'O');
                Push(&x[l],'x');
                Push(&x[l],'O');
            }
            k++;
            l = FindEmpty();
        }
        Push(&x[i],'v');
        //Push(&x[i],'O');
        //i = FindTop('O');
    //}
    if (dump.kata[0] == '(') {
        checkBuKu(&dump,cek);
        if ((*cek)  != false) {
            if (isSameOperasi(dump)) {
/*
                i = FindTop('O');
                Pop(&x[i],&c);
                Push(&x[i],'O');
                Push(&x[i],'x');
                Push(&x[i],'O');
*/
                checkO(&dump,cek);
/*
                if ((*cek) != false) {
                    dox(&dump,cek);
                }
                if ((*cek)  != false) {
                    doO(&dump,cek);
                }
*/
            } else {
                doO(&dump,cek);
            }
        }
        if ((*cek)  != false) {
            checkTuKu(&dump,cek);
        }
    } else if (isSameOperasi(dump)) {
        m = 0;
        while (m < 9) {
            if (!IsEmpty(x[m])) {
                if (InfoTop(x[m]) != 'O') {
                    DeleteStack(&x[m]);
                }
            }
            m++;
        }
        doO(&dump,cek);
        dox(&dump,cek);
        i = FindTop('O');
        while (!IsVariabel(dump)) {
            if (dump.kata[0] != '(') {
                Pop(&x[i],&c);
                Push(&x[i],'O');
                Push(&x[i],'x');
                Push(&x[i],'O');
                doO(&dump,cek);
                dox(&dump,cek);
            } else {
                Pop(&x[i],&c);
                Push(&x[i],')');
                Push(&x[i],'O');
                Push(&x[i],'(');
                checkBuKu(&dump,cek);
                doO(&dump,cek);
                checkTuKu(&dump,cek);
            }
        }
        Pop(&x[i],&c);
        Push(&x[i],'v');
        dov(dump,cek);
    } else {
        dov(dump,cek);
    }
    (*kataTemp) = getSubString((*kataTemp),j+1,(*kataTemp).length);
}

void doO (myKata * kataTemp, boolean *cek) {
    char c;
    int i;
    int k;
    int l;
    int m;
    boolean a = false;
    int j = 0;
    myKata dump;
    Stack dummy;
    createEmpty(&dump);
    i = FindTop('O');
    //while (i < 9) {
    while (!IsOperator((*kataTemp),j) && (j != (*kataTemp).length) && ((*kataTemp).kata[j] != ')')) {
        dump.kata[j] = (*kataTemp).kata[j];
        j++;
    }
    dump.length = j;

    //while (i < 9) {
        Pop(&x[i],&c);
        l = FindEmpty();
        k = 0;
        while (k < 2) {
            CreateEmpty(&dummy);
            while(!IsEmpty(x[i])) {
                Pop(&x[i],&c);
                Push(&dummy,c);
            }
            while(!IsEmpty(dummy)) {
                Pop(&dummy,&c);
                Push(&x[l],c);
                Push(&x[i],c);
            }
            if (k == 0) {
                Push(&x[l],')');
                Push(&x[l],'O');
                Push(&x[l],'(');
            } else if (k == 1) {
                Push(&x[l],'O');
                Push(&x[l],'x');
                Push(&x[l],'O');
            }
            k++;
            l = FindEmpty();
        }
        Push(&x[i],'v');
        //Push(&x[i],'O');
        //i = FindTop('O');
    //}
    if (dump.kata[0] == '(') {
        checkBuKu(&dump,cek);
        if ((*cek)  != false) {
            checkO(&dump,cek);
        }
        if ((*cek)  != false) {
            checkTuKu(&dump,cek);
        }
    } else if (isSameOperasi(dump)) {
        doO(&dump,cek);
        if ((*cek) != false) {
            dox(&dump,cek);
        }
        if ((*cek)  != false) {
            doO(&dump,cek);
        }
    } else {
        dov(dump,cek);
    }
    (*kataTemp) = getSubString((*kataTemp),j+1,(*kataTemp).length);
}

void dox (myKata * kataTemp, boolean * cek) {
    char c;
    int i;
    int j = 0;
    i = FindTop('x');
    while (i < 9) {
        if(IsOperator((*kataTemp),0)) {
            if(IsOperator(*kataTemp,1)){
                (*cek) = false;
            }
        }
        Pop(&x[i],&c);
        i = FindTop('x');
    }
    (*kataTemp) = getSubString((*kataTemp),j+2,(*kataTemp).length);
}

void dop (myKata * kataTemp, boolean * cek) {
    char c;
    int i;
    int j = 0;
    i = FindTop('p');
    while (i < 9) {
        if ((*kataTemp).kata[0] == '<') {
            if (((*kataTemp).kata[1] == '=') || ((*kataTemp).kata[1] == '>')) {
                Pop(&x[i],&c);
                j = 2;
            } else if (!IsPembanding((*kataTemp),1)) {
                Pop(&x[i],&c);
                j = 1;
            } else {
                (*cek) = false;
            }
        } else if ((*kataTemp).kata[0] == '>') {
            if (((*kataTemp).kata[1] == '=')) {
                Pop(&x[i],&c);
                j = 2;
            } else if (!IsPembanding((*kataTemp),1)) {
                Pop(&x[i],&c);
                j = 1;
            } else {
                (*cek) = false;
            }
        } else if ((*kataTemp).kata[0] == '=') {
            if (!IsPembanding((*kataTemp),1)) {
                Pop(&x[i],&c);
                j = 1;
            } else {
                (*cek) = false;
            }
        } else {
            (*cek) = false;
        }
        i = 9;
    }
    (*kataTemp) = getSubString((*kataTemp),j+1,(*kataTemp).length);
}

void dov (myKata temp, boolean * cek) {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'v') {
                if (IsVariabel(temp)) {
                    Pop(&x[i],&c);
                } else {
                    DeleteStack(&x[i]);
                    (*cek) = false;

                }
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
}

void doy (myKata * kataTemp, boolean *cek) {
    char c;
    int i;
    int j = 0;
    myKata dump;
    createEmpty(&dump);
    i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'y') {
                while (!IsOperator((*kataTemp),j) && (j != (*kataTemp).length-1) && ((*kataTemp).kata[j] != '=')) {
                    dump.kata[j] = (*kataTemp).kata[j];
                    j++;
                }
                dump.length = j;
                if (IsVar(dump)) {
                    Pop(&x[i],&c);
                } else {
                    (*cek) = false;
                }
            } else {
                DeleteStack(&x[i]);
            }
        }
        i++;
    }
    (*kataTemp) = getSubString((*kataTemp),j+1,(*kataTemp).length);
}

void dosd(myKata *kataTemp,boolean *cek) {
    char c;
    int i;
    int j = 0;
    i = FindTop('=');
    while (i < 9) {
        if((*kataTemp).kata[0] == '=') {
            if(IsOperator((*kataTemp),1) || ((*kataTemp).kata[1] == '=')) {
                (*cek) = false;
            }
            else {
                Pop(&x[i],&c);
            }
        }
        i = FindTop('=');
    }
    (*kataTemp) = getSubString((*kataTemp),j+2,(*kataTemp).length);
}

void dob () {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'b') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void doe () {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'e') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dow() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'w') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dobk() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == '{') {
                Pop(&x[i],&c);
                i++;
                
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dotk() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == '}') {
                Pop(&x[i],&c);
                i++;

            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dod() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'd') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dor() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'r') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dou() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'u') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dom () {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'm') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void doo () {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'o') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void doi() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'i') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void dot() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 't') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void don() {
    char c;
    int i = 0;
    while (i < 9) {
        if (!IsEmpty(x[i])) {
            if (InfoTop(x[i]) == 'n') {
                Pop(&x[i],&c);
                i++;
            } else {
                DeleteStack(&x[i]);
                i++;
            }
        } else {
            i++;
        }
    }
    FixArray();
}

void doBuCond (myKata *temp, boolean * cek) {
    checkBuKu(temp,cek);
    if (*cek) {
        checkO(temp,cek);
    }
    dop(temp,cek);
    if (*cek) {
        checkO(temp,cek);
    }
    if (*cek) {
        checkTuKu(temp,cek);
    }
}

void doBuOp (myKata *temp, boolean * cek, int i) {
    checkBuKu(temp,cek);
    if (*cek) {
        if (InfoTop(x[i]) == 'O') {
            checkO(temp,cek);
        } else {
            (*cek) = false;
        }
    }
    if (*cek) {
        checkTuKu(temp,cek);
    }
}

void doBuVar (myKata *temp, boolean * cek, int i) {
    checkBuKu(temp,cek);
    if (InfoTop(x[i]) == 'y') {
        if (*cek) {
            doy(temp,cek);
        }
    } else if (InfoTop(x[i]) == 'O') {
        if (*cek) {
            checkO(temp,cek);
        }
    }
    if (*cek) {
        checkTuKu(temp,cek);
    }
}